#include "my_uart.h"
#include "my_uart_app.h"
#include "sys_param.h"
#include "flash.h"

UART_PARAM_t uart_data;
uint32_t ulTemp;

static uint8_t u8_iap_ack_Data[]={0x6D,0xAC,0x00,0xFF,0x0A,0x00,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCF,0x68};
uint8_t uart_printf_flag = 0;


/******************************************************************************
* FunctionName : crc16_compute(uint8_t const * p_data, uint32_t size, uint16_t const * p_crc)
* Description : CRC校验
* EntryParameter : None
* ReturnValue : None
******************************************************************************/
uint16_t crc16_compute(uint8_t const * p_data, uint32_t size)
{
    uint16_t crc =0xFFFF;
    uint32_t    i;

    for (i = 0; i < size; i++)
    {
        crc = (uint8_t)(crc >> 8) | (crc << 8);
        crc ^= p_data[i];
        crc ^= (uint8_t)(crc & 0xFF) >> 4;
        crc ^= (crc << 8) << 4;
        crc ^= ((crc & 0xFF) << 4) << 1;
    }
    return crc;
}


/****************************
* 清空串口超时 计数
*******************************/ 
void clear_uart_recv_timeout(void)
{
    uart_data.recv_timeout_cnt = 0;
}

/****************************
* 串口超时 计数 ++
*******************************/ 
void uart_recv_timeout_check(void)
{
    uint8_t send_len;
    if(0 == uart_data.recv_flag){
        return;
    }
    uart_data.recv_timeout_cnt ++;

    // 超时后，将finish_flag 置1，
    // 超时计数清0，recv_flag清0
    if(uart_data.recv_timeout_cnt > 10){
        uart_data.recv_timeout_cnt = 0;
        uart_data.recv_flag = 0;
        uart_data.recv_finish_flag = 1;

        // send_len = uart_data.recv_num;
        // memcpy(uart_data.tx_buff, uart_data.rx_buff, send_len);

        // LPUART_Transmit(LPUART1, uart_data.tx_buff, send_len, 0xFFFFFF);
        
        // // if(gu8RxCmdTxLen)
        // // {
        // //     LPUART_TransmitIT(LPUART1, &gu8RxCmdTxLen);
        // //     gu8RxCmdTxLen--;
        // // }
        
        // printf("uart_rcv_num:[%d] \r\n", uart_data.recv_num);
        
        
        // uart_data.recv_num = 0;


    }
}

#if 0
    0XEE 08 00 04 CHARGE_STA_REQ BAT_CHARGING CRC16 （充电中）
    /*
    0xee 0x08 0x00 0x04 0x04 0x01 0x07 0x83 (主机回复给底座)
    */

/********************************************
 * 老化模式下，状态发送
 * 0xee 0x08 0x00 0x0f 0x00 0x00 crc_h  crc_l   //  主机在停止输出，在充电状态
   0xee 0x08 0x00 0x0f 0x00 0x00  0x2b  0x97

   0xee 0x08 0x00 0x0f 0x00 0x01 crc_h  crc_l   //  主机在停止充电，在输出状态
   0xee 0x08 0x00 0x0f 0x00 0x01 0x3b 0xb6
 ***********************************************/

#endif

/****************************
* 串口解析
*******************************/ 
void dealwith_uart_recv(void)
{
    uint16_t crc;
    int i;

    uart_recv_timeout_check();
    if(0 == uart_data.recv_finish_flag){
        return;
    }

    if(uart_data.recv_num > RX_TX_FRAME_LEN){
        return;
    }

    if(uart_data.recv_num <= 3){

        if((uart_data.rx_buff[0] == 0x23)||(uart_data.rx_buff[1] == 0x45)){
            uart_printf_flag = uart_printf_flag? 0:1;
        }

        // printf("===\r\n");
        uart_data.recv_num = 0;
        uart_data.recv_finish_flag = 0;
        return;
    }

    if(uart_data.rx_buff[0] !=  0xee){
        
        uart_data.recv_num = 0;
        uart_data.recv_finish_flag = 0;
        // printf(" first not 0xee \r\n");
        return;
    }

    crc = crc16_compute(uart_data.rx_buff, uart_data.recv_num - 2);

    if(crc != ((uart_data.rx_buff[uart_data.recv_num - 2]<<8)|(uart_data.rx_buff[uart_data.recv_num - 1])))
    {
        // printf("crc_check_err ,recv_len:[%d] \r\n", uart_data.recv_num);
        // printf("crc_data[%0x] \r\n", crc);

        // for(i = 0; i < uart_data.recv_num; i++){
        //     printf("rx_buff[%d]:[%0x]  ", i, uart_data.rx_buff[i]);
        // }
        // printf("===\r\n");
        uart_data.recv_num = 0;
        uart_data.recv_finish_flag = 0;
        return;
    }
    // printf(" rx_recv: \r\n");
    // for(i = 0; i < uart_data.recv_num; i++){
    //         printf("[0x%0x]-", uart_data.rx_buff[i]);
    // }
    // printf(" end \r\n"); 
       
    sys_data.host_offline_cnt = 0;

    sys_data.host_online_cnt ++;

    if(sys_data.host_online_cnt > 10){
        sys_data.host_online_flag = 1;
    }
    // printf(" clear offline cnt 1111 \r\n");
    switch (uart_data.rx_buff[3])
    {
        // 主机发给底座起始头
        case BAT_STA_CMD:{
                /* code */
            switch (uart_data.rx_buff[4])
            {
            case CHARGE_STA_ACK:
                sys_data.recv_host_msg_flag = 1;

                if(BAT_CHARGING == uart_data.rx_buff[5]){
                    sys_data.host_charging_flag = 1;
                    sys_data.host_charg_full_flag = 0;
                }
                else{
                    sys_data.host_charging_flag = 0;
                    sys_data.host_charg_full_flag = 1;
                }
                /* code */
                break;
            
            default:
                break;
            }
            break;
        }
        case ALING_STA_CMD:{
            switch (uart_data.rx_buff[5]){
                case ALING_MODE_CHARG_STA:{
                    sys_data.force_dischage_cnt = 0;
                    // 在充电状态，打开充电使能
                    set_sys_sta(ALING_CHARGE_STA);
                    break;
                }
                case ALING_MODE_OUTPUT_STA:{
                    // sys_data.force_dischage_cnt = 1;
                    set_sys_sta(ALING_DIS_CHARGE_STA);
                    printf("==ALING_DIS_CHARGE_STA =\r\n");
                    break;
                }
                default:{
                    break;
                }
            }
            break;
        }
    default:
        break;
    }
    memset(uart_data.rx_buff, 0, uart_data.recv_num);
}

#if 0
    底座给主机(查询充电状态)
    0XFF 08 00 04 CHARGE_STA_REQ 00 CRC16
    /**
    0xff 0x08 0x00 0x04 0x03 0x00 0xd1 0x11
    **/
#endif
/****************************
* 1s 一次的状态查询指令
*******************************/ 
void base_charge_sta_req(void)
{
    uint16_t crc;

    uart_data.tx_buff[0] = 0xff;
    uart_data.tx_buff[1] = 0x08;
    uart_data.tx_buff[2] = 0x00;
    uart_data.tx_buff[3] = 0x04;

    uart_data.tx_buff[4] = 0x03;
    uart_data.tx_buff[5] = 0x00;
    crc = crc16_compute(uart_data.tx_buff, 6);

    uart_data.tx_buff[6] = crc>>8;
    uart_data.tx_buff[7] = crc&0xff;

    LPUART_Transmit(LPUART1, uart_data.tx_buff, 8, 0xFFFFFF);
}

void base_err_sta_check(void)
{
    base_charge_sta_req();
    sys_data.host_offline_cnt ++;
    if(sys_data.host_offline_cnt > 10){
        sys_data.host_online_cnt = 0;
        sys_data.host_online_flag = 0;
        sys_data.host_charging_flag = 0;
        sys_data.host_charg_full_flag = 0;
        return;
    }



    /**************
     * 如果 uart通讯在线，如果主机识别到adc在线，底座未识别到充电状态，则底座的原因
     * 也可能是接触不良
     * */ 




}




/****************************
* 获取串口接收flag
*******************************/ 
uint8_t get_uart_recv_finish_flag(void)
{
    return uart_data.recv_finish_flag;
}

/****************************
* 串口中断处理
*******************************/ 
void LpUart1_IRQHandler(void)
{
    if(LPUART_GetFlag(LPUART1, LPUART_FLAG_RC))
    {   // 接收中断
        if(LPUART_GetFlag(LPUART1, LPUART_FLAG_PE|LPUART_FLAG_FE))
        {
            ///< 错误处理……
            LPUART_ClearIrq(LPUART1, LPUART_FLAG_PE|LPUART_FLAG_FE);
        }
        else
        {
            LPUART_ReceiveIT(LPUART1, &uart_data.rx_buff[uart_data.recv_num]);
            LPUART_ClearIrq(LPUART1, LPUART_FLAG_RC);
            LPUART_EnableIrq(LPUART1, LPUART_INT_TXE);
            LPUART_DisableIrq(LPUART1, LPUART_INT_RC);
            //----------自己用到的部分------
            uart_data.recv_num ++;
            uart_data.recv_num = uart_data.recv_num%RX_TX_FRAME_LEN;
            uart_data.recv_flag = 1;
            clear_uart_recv_timeout();
            
            // 上位机升级软件 触发握手
            if(uart_data.recv_num >=18){
                // u8RxCnt = 0;
                if ((uart_data.rx_buff[0]==0x6D)&&(uart_data.rx_buff[1]==0xAC)&&(uart_data.rx_buff[6]==0x26)&&(uart_data.rx_buff[16]==0xA6)&&(uart_data.rx_buff[17]==0xDA)) //��APP����֡
                {
                    LPUART_Transmit(LPUART1, (uint8_t *)u8_iap_ack_Data, 18, 10000);
                    //boot para����д���ֵ,֪ͨBootLoaderҪ���³�����
                    FLASH_SectorErase(0xF00);
                    ulTemp = 0x67890123;
                    FLASH_WriteWord(0xF00, &ulTemp, 1);
                    NVIC_SystemReset();  //������λMCU
                }     
            }
        }
    }
    
    if(LPUART_GetFlag(LPUART1, LPUART_FLAG_TXE))
    {
        LPUART_ClearIrq(LPUART1, LPUART_FLAG_TXE);
        // if(gu8RxCmdTxLen)
        // {
        //     LPUART_TransmitIT(LPUART1, &gu8RxCmdTxLen);
        //     gu8RxCmdTxLen--;
        // }
        // else
        // {
            LPUART_EnableIrq(LPUART1, LPUART_INT_RC);
            LPUART_DisableIrq(LPUART1, LPUART_INT_TXE);
        // }
    }
}




